/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file   fatfs.c
  * @brief  Code for fatfs applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
#include "fatfs.h"

uint8_t retUSBH;    /* Return value for USBH */
char USBHPath[4];   /* USBH logical drive path */
FATFS USBHFatFS;    /* File system object for USBH logical drive */
FIL USBHFile;       /* File object for USBH */
uint8_t retUSER;    /* Return value for USER */
char USERPath[4];   /* USER logical drive path */
FATFS USERFatFS;    /* File system object for USER logical drive */
FIL USERFile;       /* File object for USER */

/* USER CODE BEGIN Variables */
static uint8_t flashFlag = 0;
extern struct systemTime_t sysTime;
static UINT fnum;
static BYTE ReadBuffer[20] = {0};                         
static BYTE WriteBuffer_Title[] = "This Is File Test\r\n"; 
static uint8_t fileSPIWriteFlag = 0;

uint8_t exf_getfree(uint8_t *drv, uint32_t *total, uint32_t *free);
void FileReadWriteTest(void);
/* USER CODE END Variables */

void MX_FATFS_Init(void)
{
  /*## FatFS: Link the USBH driver ###########################*/
  retUSBH = FATFS_LinkDriver(&USBH_Driver, USBHPath);
  /*## FatFS: Link the USER driver ###########################*/
  retUSER = FATFS_LinkDriver(&USER_Driver, USERPath);

  /* USER CODE BEGIN Init */
  /* additional user code for init */
  /* USER CODE END Init */
}

/**
  * @brief  Gets Time from RTC
  * @param  None
  * @retval Time in DWORD
  */
DWORD get_fattime(void)
{
  /* USER CODE BEGIN get_fattime */
  return 0;
  /* USER CODE END get_fattime */
}

/* USER CODE BEGIN Application */


void InitFatFs_SPI_FLASH(void)
{
  uint32_t  buf[4096];
  retUSER = f_mount(&USERFatFS, USERPath, 1);
  if (retUSER != FR_OK)
  {
    printf("SPI Flash is not formatted\r\n");
    retUSER = f_mkfs(USERPath,FM_FAT32,512,buf, 512); // format once, otherwise the file system records incorrectly
    // f_mkfs the function takes an extremely long time, possibly up to 10 minutes, which is related to the capacity of the SD card?
    if (retUSER == FR_OK)
    {
      printf("The FLASH formats the file system successfully\r\n");
      retUSER = f_mount(NULL, (TCHAR const *)USERPath, 1);
		retUSER = f_mount(&USERFatFS, (TCHAR const *)"1:", 1);  //USERPath
    }
    else
    {
      printf("Formatting failure\r\n");
    }
  }
  if (retUSER == FR_OK)
  {
    printf("Fmout OK!\r\n");
    uint32_t total;
    uint32_t free;
    if (exf_getfree((uint8_t *)"1:", &total, &free) == FR_OK)
    {
      printf("Total=%d KB,Free=%d KB\r\n", total, free);
    }
    else
    {
      printf("Disk Space Error\r\n");
    }
    flashFlag = 1;
  }
  
    flashFlag = 1;
  FileReadWriteTest();
}
 


void FileReadWriteTest(void)
{
  if (flashFlag > 0)
  {  
    printf("File Write Test\n");
#if 1
    retUSER = f_open(&USERFile, "1:/test.txt", FA_OPEN_ALWAYS | FA_WRITE);

    // f_res = f_lseek(&SDFile, f_size(&SDFile));
    if (retUSER == FR_OK)
    {
      printf("Write To file\n");
      retUSER = f_write(&USERFile, WriteBuffer_Title, sizeof(WriteBuffer_Title), &fnum);
      if (retUSER == FR_OK)
      {
        printf("Write Len=%d\n", fnum);
        printf("Write Data:\n%s\n", WriteBuffer_Title);
      }
      else
      {
        printf("Write Fail,Error Code(%d)\n", retUSER);
      }
      f_close(&USERFile);
    }
    else
    {
      printf("open or create file failed\n");
    }
 
    /*------------------- file system read data test-----------------------------------*/
    printf("File Read Test\n");
    // HAL_IWDG_Refresh(&hiwdg);
    retUSER = f_open(&USERFile, "1:/test.txt", FA_OPEN_EXISTING | FA_READ);
    fileSPIWriteFlag = 1;
    // f_res = f_lseek(&SDFile, 2);
    if (retUSER == FR_OK)
    {
      printf("File Opend\r\n");
 
      retUSER = f_read(&USERFile, ReadBuffer, sizeof(ReadBuffer), &fnum);
      if (retUSER == FR_OK)
      {
        printf("Read Len=%d\n", fnum);
        printf("Read Data:\n%s \n", ReadBuffer);
      }
      else
      {
        printf("Read Fail,Error Code(%d)\n", retUSER);
      }
    }
    else
    {
      printf("File Open Failed\n");
    }
    f_close(&USERFile);
    fileSPIWriteFlag = 0;
#endif
	
  }
}

uint8_t exf_getfree(uint8_t *drv, uint32_t *total, uint32_t *free)
{
  FATFS *fs1;
  uint8_t res;
  DWORD fre_clust = 0;
  uint32_t fre_sect = 0, tot_sect = 0;
  // ????????????
  res = f_getfree((const TCHAR *)drv, &fre_clust, &fs1);
  if (res == 0)
  {
    tot_sect = (fs1->n_fatent - 2) * fs1->csize; // ??????
    fre_sect = fre_clust * fs1->csize;           // ??????????
#if _MAX_SS != 512                               // ??????512??,????512??
    tot_sect *= fs1->ssize / 512;
    fre_sect *= fs1->ssize / 512;
#endif
    *total = tot_sect >> 1; // ???KB
    *free = fre_sect >> 1;  // ???KB
  }
  return res;
}

/* USER CODE END Application */
